/*
 * UnboundedBlockingQueue.cpp
 *
 *  Created on: Jun 26, 2009
 *      Author: elkobir
 */

#include "UnboundedBlockingQueue.h"

UnboundedBlockingQueue::UnboundedBlockingQueue() {
	_queue = new list<string>();

	// Initialize _sync mutex
	if (pthread_mutex_init(&_sync, NULL) != 0)
	{
		perror("_sync mutex initialization error");
		exit(1);
	}
	pthread_mutex_init(&_emptyMutex, NULL);
	pthread_cond_init(&_emptyCond, NULL);

}

UnboundedBlockingQueue::~UnboundedBlockingQueue() {
	pthread_mutex_destroy(&_sync);
	pthread_mutex_destroy(&_emptyMutex);
	pthread_cond_destroy(&_emptyCond);
}


bool UnboundedBlockingQueue::addElement(string msg){
	pthread_mutex_lock(&_sync); /* enter critical section */
	_queue->push_back(msg); /* insert into queue */
	pthread_cond_signal(&_emptyCond); // wake up
	pthread_mutex_unlock(&_sync); /* leave critical section */
	return true;
}

string UnboundedBlockingQueue::removeElement(){
	pthread_mutex_lock(&_sync); /* enter critical section */
	while(this->_queue->empty()){
		pthread_cond_wait(&_emptyCond, &_sync); // sleep if empty
	}
	string msg = _queue->front(); /* getting the first element */
	_queue->pop_front(); /* removing the first element */
	pthread_mutex_unlock(&_sync); /* leave critical section */
	return msg;
}

bool UnboundedBlockingQueue::isEmpty()
{
	bool result = false;
	pthread_mutex_lock(&_sync); /* enter critical section */
	result = (_queue->size() == 0); /* getting the first element */
	pthread_mutex_unlock(&_sync); /* leave critical section */
	return result;
}


